package com.ruoyi.standingbook.recycle.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.asset.homepage.enums.ServiceTypeEnum;
import com.ruoyi.asset.recycle.constant.WasteRecycleDirtConstant;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.DictService;
import com.ruoyi.common.domain.vo.RecycleErecordVo;
import com.ruoyi.common.domain.vo.StatisticsRecycleVo;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.standingbook.recycle.domain.Recycle;
import com.ruoyi.standingbook.recycle.domain.bo.RecycleBo;
import com.ruoyi.standingbook.recycle.domain.bo.RecyclePicBo;
import com.ruoyi.standingbook.recycle.domain.vo.RecycleImportDetailVo;
import com.ruoyi.standingbook.recycle.domain.vo.RecyclePicVo;
import com.ruoyi.standingbook.recycle.domain.vo.RecycleVo;
import com.ruoyi.standingbook.recycle.mapper.RecycleMapper;
import com.ruoyi.standingbook.recycle.service.IRecycleService;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.apache.http.client.utils.DateUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 垃圾清运Service业务层处理
 *
 * @author cc
 * @date 2023-04-28
 */
@RequiredArgsConstructor
@Service
public class RecycleServiceImpl implements IRecycleService {

    private final RecycleMapper baseMapper;
    private final ISysDictDataService sysDictDataService;

    private DictService dictService = SpringUtils.getBean(DictService.class);

    /**
     * 查询垃圾清运
     */
    @Override
    public RecycleVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询垃圾清运列表
     */
    @Override
    public TableDataInfo<RecycleVo> queryPageList(RecycleBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Recycle> lqw = buildQueryWrapper(bo);
        Page<RecycleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        for(RecycleVo rv:result.getRecords()){
           String garbageCategoryText=this.dictService.getDictLabel("erecord_recycle_garbage_category", rv.getGarbageCategory());
           rv.setGarbageCategoryText(garbageCategoryText);
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询垃圾清运列表
     */
    @Override
    public List<RecycleVo> queryList(RecycleBo bo) {
        LambdaQueryWrapper<Recycle> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询Excel垃圾清运列表
     */
    @Override
    public List<RecycleVo> queryExcelList(RecycleBo bo) {
        LambdaQueryWrapper<Recycle> lqw = buildExcelQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Recycle> buildQueryWrapper(RecycleBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Recycle> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getClearingTransportationUnitName()), Recycle::getClearingTransportationUnitName, bo.getClearingTransportationUnitName());
        lqw.like(StringUtils.isNotBlank(bo.getTransportationPersonnelName()), Recycle::getTransportationPersonnelName, bo.getTransportationPersonnelName());
        lqw.like(StringUtils.isNotBlank(bo.getItemName()), Recycle::getItemName, bo.getItemName());
        lqw.like(StringUtils.isNotBlank(bo.getLicensePlateNumber()), Recycle::getLicensePlateNumber, bo.getLicensePlateNumber());
        lqw.like(StringUtils.isNotBlank(bo.getClearingPersonnelName()), Recycle::getClearingPersonnelName, bo.getClearingPersonnelName());
        lqw.eq(StringUtils.isNotBlank(bo.getGarbageCategory()), Recycle::getGarbageCategory, bo.getGarbageCategory());
        lqw.between(params.get("beginDate") != null && params.get("endDate") != null,
            Recycle::getDate ,params.get("beginDate"), params.get("endDate"));
        lqw.orderByDesc(Recycle::getCreateTime);
        lqw.orderByDesc(Recycle::getDate);
        return lqw;
    }

    private LambdaQueryWrapper<Recycle> buildExcelQueryWrapper(RecycleBo bo) {
        Map<String, Object> params = bo.getParams();
        if(params.get("endDate") == null){
            params.put("endDate",DateUtils.formatDate(new Date(), "yyyy-MM-dd"));
        }
        LambdaQueryWrapper<Recycle> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getGarbageCategory()), Recycle::getGarbageCategory, bo.getGarbageCategory());
        lqw.eq(params.get("endDate") != null, Recycle::getDate , params.get("endDate").toString().substring(0,10));
        lqw.orderByDesc(Recycle::getCreateTime);
        lqw.orderByDesc(Recycle::getDate);
        return lqw;
    }

    /**
     * 新增垃圾清运
     */
    @Override
    public Boolean insertByBo(RecycleBo bo) {
        Recycle add = BeanUtil.toBean(bo, Recycle.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改垃圾清运
     */
    @Override
    public Boolean updateByBo(RecycleBo bo) {
        Recycle update = BeanUtil.toBean(bo, Recycle.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Recycle entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除垃圾清运
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 批量插入
     */
    @Override
    public Boolean batchInsert(List<RecycleImportDetailVo> voList) {
        if (null != voList && !voList.isEmpty()) {
            Date date = voList.get(0).getDate();
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            LambdaQueryWrapper<Recycle> lqw = Wrappers.lambdaQuery();
            lqw.eq(Recycle::getDate, date);
            this.baseMapper.delete(lqw);
        }

        List<Recycle> list = BeanCopyUtils.copyList(voList, Recycle.class);
        list.forEach(e -> {
            e.setId(null);
            e.restBase();
        });
        return this.baseMapper.insertBatch(list);
    }

    /**
     * 获取垃圾清运电子档案信息
     *
     * @param bo
     * @return
     */
    public RecycleErecordVo getRecycleErecordInfo(RecycleBo bo) {
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(bo.getDate())) {
            throw new RuntimeException("日期不能为空");
        }
        RecycleErecordVo rev = new RecycleErecordVo();
        List<StatisticsRecycleVo> todayBarrelageList = baseMapper.statisticsTodayBarrelageList();
        rev.setBarrelageTodayList(todayBarrelageList);  //清运桶数列表当天列表
        List<StatisticsRecycleVo> monthBarrelageList = baseMapper.statisticsMonthBarrelageList(bo);
        rev.setBarrelageMonthList(monthBarrelageList); //清运桶数列表月列表
        List<StatisticsRecycleVo> todayCarNumberList = baseMapper.statisticsTodayCarNumberList();
        rev.setCarNumberTodayList(todayCarNumberList);  //车辆数列表当天列表
        List<StatisticsRecycleVo> monthCarNumberList = baseMapper.statisticsMonthCarNumberList(bo);
        rev.setCarNumberMonthList(monthCarNumberList); //车辆数列表月列表

        //汇总今日桶数和重量
        Long todayBarrelage = 0L;
        Double todayWeight = 0d;
        boolean categoryFlag1 = false;
        boolean categoryFlag2 = false;
        boolean categoryFlag3 = false;
        System.out.println("todayBarrelageList"+todayBarrelageList.size());
        for (StatisticsRecycleVo rv : todayBarrelageList) {
            //厨余垃圾、生活垃圾桶数   废旧家具清运重量
            if (rv.getGarbageCategory().equals("1")) {
                todayBarrelage += rv.getBarrelage();
                categoryFlag1 = true;
            } else if (rv.getGarbageCategory().equals("2")) {
                todayWeight += rv.getWeight();
                categoryFlag2 = true;
            } else if (rv.getGarbageCategory().equals("3")) {
                todayBarrelage += rv.getBarrelage();
                categoryFlag3 = true;
            }
        }
        //合并月数据到今日统计列表
        for (StatisticsRecycleVo rv : monthBarrelageList) {
            for (StatisticsRecycleVo rv2 : todayBarrelageList) {
                if (rv.getGarbageCategory().equals(rv2.getGarbageCategory())) {
                    rv2.setThisMonthBarrelage(rv.getBarrelage());
                    rv2.setThisMonthWeight(rv.getWeight());
                    break;
                }
            }
        }

        //初始化为空数据
        if (!categoryFlag1) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("厨余垃圾清运");
            srv.setGarbageCategory("1");
            srv.setBarrelage(0L);
            todayBarrelageList.add(srv);
        }
        if (!categoryFlag2) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("废旧家具清运");
            srv.setGarbageCategory("2");
            srv.setWeight(0d);
            todayBarrelageList.add(srv);
        }
        if (!categoryFlag3) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("生活垃圾清运");
            srv.setGarbageCategory("3");
            srv.setBarrelage(0L);
            todayBarrelageList.add(srv);
        }
        rev.setTodayBarrelage(todayBarrelage);
        rev.setTodayWeight(todayWeight);
        System.out.println("todayWeight============="+todayWeight);

        //汇总当月桶数和重量
        Long thisMonthBarrelage = 0L;
        Double thisMonthWeight = 0d;
        categoryFlag1 = false;
        categoryFlag2 = false;
        categoryFlag3 = false;
        for (StatisticsRecycleVo rv : monthBarrelageList) {
            //厨余垃圾、生活垃圾桶数   废旧家具清运重量
            if (rv.getGarbageCategory().equals("1")) {
                thisMonthBarrelage += rv.getBarrelage();
                categoryFlag1 = true;
            } else if (rv.getGarbageCategory().equals("2")) {
                thisMonthWeight += rv.getWeight();
                categoryFlag2 = true;
            } else if (rv.getGarbageCategory().equals("3")) {
                thisMonthBarrelage += rv.getBarrelage();
                categoryFlag3 = true;
            }
        }
        if (!categoryFlag1) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("厨余垃圾清运");
            srv.setGarbageCategory("1");
            srv.setBarrelage(0L);
            monthBarrelageList.add(srv);
        }
        if (!categoryFlag2) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("废旧家具清运");
            srv.setGarbageCategory("2");
            srv.setWeight(0d);
            monthBarrelageList.add(srv);
        }
        if (!categoryFlag3) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("生活垃圾清运");
            srv.setGarbageCategory("3");
            srv.setBarrelage(0L);
            monthBarrelageList.add(srv);
        }
        rev.setThisMonthBarrelage(thisMonthBarrelage);
        rev.setThisMonthWeight(thisMonthWeight);

        //汇总今日车辆数
        Long todayCarNumber = 0L;
        categoryFlag1 = false;
        categoryFlag2 = false;
        categoryFlag3 = false;
        for (StatisticsRecycleVo rv : todayCarNumberList) {
            todayCarNumber += rv.getCarNumber();
            if (rv.getGarbageCategory().equals("1")) {
                categoryFlag1 = true;
            } else if (rv.getGarbageCategory().equals("2")) {
                categoryFlag2 = true;
            } else if (rv.getGarbageCategory().equals("3")) {
                categoryFlag3 = true;
            }
        }
        if (!categoryFlag1) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("厨余垃圾清运");
            srv.setGarbageCategory("1");
            srv.setCarNumber(0L);
            todayCarNumberList.add(srv);
        }
        if (!categoryFlag2) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("废旧家具清运");
            srv.setGarbageCategory("2");
            srv.setCarNumber(0L);
            todayCarNumberList.add(srv);
        }
        if (!categoryFlag3) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("生活垃圾清运");
            srv.setGarbageCategory("3");
            srv.setCarNumber(0L);
            todayCarNumberList.add(srv);
        }
        rev.setTodayCarNumber(todayCarNumber);

        //汇总本月车辆数
        Long thisMonthCarNumber = 0L;
        categoryFlag1 = false;
        categoryFlag2 = false;
        categoryFlag3 = false;
        for (StatisticsRecycleVo rv : monthCarNumberList) {
            thisMonthCarNumber += rv.getCarNumber();
            if (rv.getGarbageCategory().equals("1")) {
                categoryFlag1 = true;
            } else if (rv.getGarbageCategory().equals("2")) {
                categoryFlag2 = true;
            } else if (rv.getGarbageCategory().equals("3")) {
                categoryFlag3 = true;
            }
        }
        //合并月数据到今日统计列表
        for (StatisticsRecycleVo rv : monthCarNumberList) {
            for (StatisticsRecycleVo rv2 : todayCarNumberList) {
                if (rv.getGarbageCategory().equals(rv2.getGarbageCategory())) {
                    rv2.setThisMonthCarNumber(rv.getCarNumber());
                    break;
                }
            }
        }

        if (!categoryFlag1) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("厨余垃圾清运");
            srv.setGarbageCategory("1");
            srv.setCarNumber(0L);
            monthCarNumberList.add(srv);
        }
        if (!categoryFlag2) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("废旧家具清运");
            srv.setGarbageCategory("2");
            srv.setCarNumber(0L);
            monthCarNumberList.add(srv);
        }
        if (!categoryFlag3) {
            StatisticsRecycleVo srv = new StatisticsRecycleVo();
            srv.setGarbageCategoryName("生活垃圾清运");
            srv.setGarbageCategory("3");
            srv.setCarNumber(0L);
            monthCarNumberList.add(srv);
        }
        rev.setThisMonthCarNumber(thisMonthCarNumber);
        return rev;
    }

    @Override
    public List<RecycleVo> queryListByDate(String date) {
        LambdaQueryWrapper<Recycle> lqw = Wrappers.lambdaQuery();
        lqw.eq(Recycle::getDate,date);
        lqw.orderByDesc(Recycle::getWeight);
        List<RecycleVo> recycleVos = baseMapper.selectVoList(lqw);
        recycleVos.forEach(e->{
            String garbageType = sysDictDataService.selectDictLabel(WasteRecycleDirtConstant.GARBAGE_CATEGORY, e.getGarbageCategory());
            if (StringUtils.isNotBlank(garbageType)) {
                e.setGarbageCategoryText(garbageType);
            }
            e.setServiceTypeName(ServiceTypeEnum.RECYCLE.getTypeName());
        });
        return recycleVos;
    }

    @Override
    public List<RecyclePicVo> getCheckedPicByDate(String date) {
        List<RecyclePicBo> recyclePicBos = baseMapper.selectPicByDate(date);
        List<RecyclePicVo> pics = new ArrayList<>();
        recyclePicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic1())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic1());
                pics.add(recyclePicVo);
            }
            if (StringUtils.isNotBlank(e.getPic2())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic2());
                pics.add(recyclePicVo);
            }
        });
        return pics;
    }

    @Override
    public List<RecyclePicVo> getCleaningPicByDate(String date) {
        List<RecyclePicBo> recyclePicBos = baseMapper.selectPicByDate(date);
        List<RecyclePicVo> pics = new ArrayList<>();
        recyclePicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic3())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic3());
                pics.add(recyclePicVo);
            }
            if (StringUtils.isNotBlank(e.getPic4())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic4());
                pics.add(recyclePicVo);
            }
        });
        return pics;
    }

    @Override
    public List<RecyclePicVo> getComingPicByDate(String date) {
        List<RecyclePicBo> recyclePicBos = baseMapper.selectPicByDate(date);
        List<RecyclePicVo> pics = new ArrayList<>();
        recyclePicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic5())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic5());
                pics.add(recyclePicVo);
            }
            if (StringUtils.isNotBlank(e.getPic6())){
                RecyclePicVo recyclePicVo = new RecyclePicVo();
                recyclePicVo.setPic(e.getPic6());
                pics.add(recyclePicVo);
            }
        });
        return pics;
    }

    @Override
    public Double getWeightSumByDate(String date) {
        List<Double> weightSum = baseMapper.selectSumByDate(date);
        if (weightSum.size() > 0) {
            return weightSum.stream().reduce(Double::sum).orElse(0.00);
        } else {
            return 0.00;
        }
    }

    @Override
    public Integer getBarrelageByYearToNow() {
        return baseMapper.statisticsBarrelageYearToNow();
    }

}
